package com.nintendo;

import com.nintendo.mq.RabbitMQConnectUtils;
import com.nintendo.utils.JedisPoolUtil;
import com.nintendo.utils.ZookeeperRegister;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import com.nintendo.socket.WSServerInitializer;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class ChatServer {
    public static final Integer nettyDefaultPort = 875;
    public static final String initOnlineCounts = "0";

    public static Integer selectPort(Integer port) {
        String portKey = "netty_port";
        Jedis jedis = JedisPoolUtil.getJedis();
        Map<String, String> portMap = jedis.hgetAll(portKey);
        System.out.println(portMap);
        List<Integer> portList = portMap.entrySet().stream().map(entry -> Integer.valueOf(entry.getKey())).collect(Collectors.toList());
        System.out.println(portList);
        Integer nettyPort = null;
        if (portList == null || portList.isEmpty()) {
            jedis.hset(portKey, port + "", initOnlineCounts);
            nettyPort = port;
        } else {
            Optional<Integer> maxInteger = portList.stream().max(Integer::compareTo);
            Integer maxPort = maxInteger.get().intValue();
            Integer currentPort = maxPort + 10;
            jedis.hset(portKey, currentPort + "", initOnlineCounts);
            nettyPort = currentPort;
        }
        return nettyPort;
    }

    @Test
    public void test() {
        Jedis jedis = JedisPoolUtil.getJedis();
        String portKey = "netty_port"; // Hash 键
        String endKey = "885";           // 待删除字段

        // 删除字段
        Long deletedCount = jedis.hdel(portKey, endKey);
        System.out.println("删除字段数量: " + deletedCount); // 成功返回1，失败返回0

        // 验证删除结果
        Boolean exists = jedis.hexists(portKey, endKey);
        System.out.println("字段是否存在: " + exists); // 应返回 false[6,7](@ref)
    }

    public static void main(String[] args) throws Exception {

        // 定义主从线程组
        // 定义主线程池，用于接受客户端的连接，但是不做任何处理，比如老板会谈业务，拉到业务就会交给下面的员工去做了
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        // 定义从线程池，处理主线程池交过来的任务，公司业务员开展业务，完成老板交代的任务
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        Integer nettyPort = selectPort(nettyDefaultPort);
        ZookeeperRegister.registerNettyServer("server-list", "192.168.108.1", nettyPort);
        // 启动消费者进行监听 队列可以根据动态生成的端口进行动态拼接
        String queueName = "netty_queue_" + nettyPort;
        RabbitMQConnectUtils rabbitMQConnection = new RabbitMQConnectUtils();
        rabbitMQConnection.listen("fanout_exchange_imooc", queueName);

        try {
            // 构建Netty服务器
            ServerBootstrap server = new ServerBootstrap();     // 服务的启动类
            server.group(bossGroup, workerGroup)                // 把主从线程池组放入到启动类中
                    .channel(NioServerSocketChannel.class)      // 设置Nio的双向通道
                    .childHandler(new WSServerInitializer());   // 设置处理器，用于处理workerGroup

            // 启动server，并且绑定端口号875，同时启动方式为"同步"
            ChannelFuture channelFuture = server.bind(nettyPort).sync();
            // 服务器地址
            System.out.println("服务器地址：" + channelFuture.channel().localAddress());
            // 请求：http://127.0.0.1:875

            // 监听关闭的channel
            channelFuture.channel().closeFuture().sync();
        } finally {
            // 优雅的关闭线程池组
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}
